#include <iostream>
#include <string.h>
using std::cout;
using std::endl;
using std::ostream;
class cowString{
public:
    //构造函数
    cowString()
    :_pstr(new char[4+1]() + 4)
    {
        *(int *)(_pstr-4) = 1; //引用计数设为1

    }
    cowString(const char * pstr)
    :_pstr(new char[strlen(pstr) + 4 + 1]() + 4)
    {
        strcpy(_pstr,pstr);
        *(int *)(_pstr-4) = 1; //引用计数设为1
    }
    cowString(const cowString & rhs)
    :_pstr(rhs._pstr)
    {
        *(int *)(_pstr-4) += 1;
    }
    cowString & operator=(const cowString & rhs){
        if(this != &rhs){
            if(--*(int*)(_pstr-4) == 0){
                delete [] (_pstr-4);
            }
            _pstr = rhs._pstr;
            ++*(int *)(_pstr - 4) ;
        }
        return *this;
    }
    ~cowString(){
        if(--*(int *)(_pstr-4) == 0){
            delete [] (_pstr - 4);
        }
    }
    
    char * c_str(){
        return _pstr;
    }
    int size(){
        return strlen(_pstr);
    }
    int refcount(){
        return *(int *)(_pstr-4);
    }

private:
    //将str[xxx]的返回值转换为自定义类型charProxy
    class charProxy{
    public:
        charProxy(cowString & cowstr,int index);
        friend ostream & operator<<(ostream & os, const cowString::charProxy & rhs);
        char & operator=(char ch);
    private:
        cowString & _cowstr;
        size_t _index;
    };

public:
    charProxy operator[](size_t index){ //[]要写到charProxy后，否则无法识别
        return charProxy(*this,index);
    } 
    friend ostream & operator<<(ostream & os, const cowString::charProxy & rhs);
private:
    //_pstr的前四个字节用来计数
    char * _pstr;
};
//内部类的构造函数
cowString::charProxy::charProxy(cowString & cowstr, int index)
:_cowstr(cowstr)
,_index(index)
{
}
//重载<<运算符
ostream & operator<<(ostream & os, const cowString::charProxy & rhs){
    if(rhs._index >= rhs._cowstr.size()){ //越界
        static char nullchar = '\0';
        os << nullchar;
    }else{
        os << rhs._cowstr._pstr[rhs._index];
    }
    return os;
}
//重载内部类的=
char & cowString::charProxy::operator=(char ch){
    if(_index >= _cowstr.size()){ //越界
        static char nullchar = '\0';
        return nullchar;
    }
    if(ch != _cowstr._pstr[_index]){
        if(_cowstr.refcount() > 1){ //非独享的情况
            //深拷贝
            char * temp = new char[_cowstr.size() + 1 + 4]() + 4;
            strcpy(temp,_cowstr.c_str());
            //原有引用计数-1
            --*(int*)(_cowstr._pstr - 4);
            //更新指向
            _cowstr._pstr = temp;
            //设置引用计数为1
            *(int*)(_cowstr._pstr - 4) = 1;
        }
        _cowstr._pstr[_index] = ch; 
    }
    return _cowstr._pstr[_index];
}


void test(){
    cowString s1("hello");
    cowString s2(s1);
    cout <<"c_str:"<< s1.c_str() << endl;
    cout <<"refcount:" <<s1.refcount() << endl;
    cout<<s1[0]<<endl;
    s1[0] = 'H';
    cout << s1.c_str()<<endl;
    cout <<"refcount:" <<s1.refcount() << endl;
    cout <<"refcount:" <<s2.refcount() << endl;

}

int main()
{
    test ();
    return 0;
}

